<template>
    <div class="lazy-tree">
        <div class="inner-wrap">
            <div class="btn-box">
                <!-- <el-button icon="iconfont icon-fujiedian" type="text" title="新增一级机构" @click="addTopNode" v-if="showAuth('FRAME_DEPT_ADD')"></el-button> -->
                <el-button icon="el-icon-circle-plus" type="text" title="新增" @click="addNode" v-if="showAuth('FRAME_DEPT_ADD')"></el-button>
                <el-button icon="el-icon-edit-outline" type="text" title="修改" :disabled="!currentNode.id" @click="editNode" v-if="showAuth('FRAME_DEPT_EDIT')"></el-button>
                <el-button icon="el-icon-delete-solid" type="text" title="删除" :disabled="!currentNode.id" @click="deleteNode" v-if="showAuth('FRAME_DEPT_DEL')"></el-button>
                <el-button icon="el-icon-top" type="text" title="上移" @click="upNode" :disabled="!currentNode.id || loading" v-if="showAuth('FRAME_DEPT_SEQ')"></el-button>
                <el-button icon="el-icon-bottom" type="text" title="下移" @click="downNode" :disabled="!currentNode.id || loading" v-if="showAuth('FRAME_DEPT_SEQ')"></el-button>
                <el-button icon="iconfont icon-plus-transfer" type="text" title="转移" @click="transNode" :disabled="!currentNode.id" v-if="showAuth('FRAME_DEPT_TRANS')"></el-button>
            </div>
            <div class="search-bar">
                <el-input v-model="filterText" placeholder="输入检索" clearable></el-input>
            </div>
            <div class="tree-box" v-loading="loading3">
                <el-tree
                    ref="tree"
                    :data="treeData"
                    :props="props"
                    accordion
                    node-key="id"
                    highlight-current
                    :show-checkbox="showCheckbox"
                    :filter-node-method="filterNode"
                    @node-click="nodeClick">
                </el-tree>
            </div>
        </div>
        <el-dialog v-dialog-drag title="机构转移" :visible.sync="show" :append-to-body="true" :close-on-click-modal="false" :before-close="closeDialog">
            <el-form :model="ruleForm" :rules="rules" label-width="100px" ref="form">
                <el-form-item label="机构：" prop="parentId">
                    <select-dept v-model="ruleForm.parentId" v-if="show" :label.sync="ruleForm.parentName" statusId=""></select-dept>
                </el-form-item>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="显示顺序：" prop="orderNum">
                            <el-input-number v-model="ruleForm.orderNum" :min="0" :max="9999"></el-input-number>
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <div slot="footer">
                <el-button type="primary" @click="submitFun" :loading="loading2">保存</el-button>
                <el-button @click="closeDialog">取消</el-button>
            </div>
        </el-dialog>
        <el-dialog v-dialog-drag title="新增部门" :visible.sync="show2" :append-to-body="true" :close-on-click-modal="false" :before-close="closeDeptDlg">
            <el-form :model="ruleForm" :rules="rules" label-width="100px" ref="form2" label-suffix="：">
                <el-form-item label="部门名称" prop="name">
                    <el-input v-model="ruleForm.name"></el-input>
                </el-form-item>
                <el-form-item label="部门主管" prop="chargUserIds">
                    <select-user v-model="ruleForm.chargUserIds" :label.sync="ruleForm.chargUserNames" multiple></select-user>
                </el-form-item>
                <el-form-item label="部门职能" prop="descr">
                    <el-input type="textarea" :rows="4" v-model="ruleForm.descr"></el-input>
                    <text-length v-model="ruleForm.descr" :length.sync="ruleForm.descr_l" :max="256"></text-length>
                </el-form-item>
                <el-form-item prop="isGroup">
                    <el-checkbox v-model="ruleForm.isGroup" :true-label="1" :false-label="0">创建群组</el-checkbox>
                </el-form-item>
            </el-form>
            <div slot="footer">
                <el-button type="primary" @click="saveDeptFun" :loading="loading4">保存</el-button>
                <el-button @click="closeDeptDlg">取消</el-button>
            </div>
        </el-dialog>
        <org-dept 
            ref="add" 
            :parentNode="currentNode"
            @updateNode="updateNodeFun"
            @appendNode="appendNodeFun">
        </org-dept>
    </div>
</template>

<script>
import orgDept from '../orgDept';
import selectDept from '@/components/selectDept';
import selectUser from '@/components/selectUser';
import textLength from '@/components/textLength';
import { initDeptTree, delDeptTree, updateDeptOrder, getDeptInfo, updateDeptTree, saveDeptTree } from "../../service.js";
import { transformTozTreeFormat } from '@/utils/Tools';
import { auth } from '@/mixins/mixins';
import { mapState } from 'vuex';

export default {
    name: 'deptTree', // 机构树
    props: {
        showCheckbox: {
            type: Boolean,
            default: false
        },
        defaultProps: {
            type: Object,
            default() {
                return {
                    label: 'name',
                    children: 'children',
                    isLeaf: 'leaf'
                }
            }
        }
    },
    components: { orgDept, selectDept, selectUser, textLength },
    mixins: [ auth ],
    computed: {
        ...mapState({
            token: state => state.token.token,
            tenementId: state => state.token.tenementId
        }),
        props() {
            return {
                label: 'name',
                children: 'children',
                isLeaf: 'leaf',
                ...this.defaultProps
            }
        }
    },
    data() {
        var validate_parentId = (rule, value, callback) => {
            if(this.ruleForm.parentId == this.currentNode.id) {
                callback(new Error());
            }else {
                callback();
            }
        }
        var validate_descr = (rule, value, callback) => {
            if(this.ruleForm.descr_l > 256) {
                callback(new Error())
            }else {
                callback();
            }
        }
        return {
            show: false,
            show2: false,
            filterText: '',
            treeData: [],
            currentNode: {}, // 选中的当前节点
            ruleForm: {
                parentId: '',
                parentName: '',
                orderNum: '',

                name: '', // 机构名称
                chargUserIds: [], // 主管
                chargUserNames: [],
                descr: '',
                descr_l: 0,
                isGroup: 0, // 是否创建群组
            },
            rules: {
                parentId: [
                    { validator: validate_parentId, message: '不能转移到当前节点自己下！', trigger: 'blur' },
                ],
                name: [
                    { required: true, message: '部门名称必填', trigger: 'change' },
                    { min: 0, max: 20, message: '长度限制20位', trigger: 'change' },
                ],
                descr: [
                    { validator: validate_descr, message: '长度限制256位', trigger: 'change' },
                ]
            },
            loading: false,
            loading2: false,
            loading3: false,
            loading4: false, // 新增机构 状态
        }
    },
    watch: {
        filterText(val) {
            this.$refs.tree.filter(val);
        }
    },
    mounted() {
        this.$nextTick(() => {
            this.deptTreeInit();
        })
    },
    methods: {
        filterNode(value, data) { // 节点过滤
            if (!value) return true;
            return data.name.indexOf(value) !== -1;
        },
        deptTreeInit() { // 初始化数据
            let params = { token: this.token, statusIds: "", columns: 'path,orderNum', orders: 'true,true' };
            this.loading3 = true;
            initDeptTree(params).then(response => {
                this.treeData.splice(0, this.treeData.length);
                if (response.data.code == 1000) {
                    let data = response.data.data;
                    data = transformTozTreeFormat(data);
                    this.treeData.push(...data);
                    if(this.treeData.length) { // 默认点击第一项
                        setTimeout(() => {
                            let Node = this.$refs.tree.getNode(this.treeData[0].id);
                            this.nodeClick(this.treeData[0], Node, this.$refs.tree);
                            this.$refs.tree.setCurrentKey(this.treeData[0].id);
                        }, 200)
                    }
                }
                this.loading3 = false;
            }).catch(error => {
                this.loading3 = false;
            })
        },
        addTopNode() { // 新增一级机构
            this.$refs.add.addTopNode();
        },
        addNode() { // 新增节点
            // this.$refs.add.showLayout();
            this.show2 = true;
        },
        editNode() { // 修改节点
            this.$refs.add.showLayout(this.currentNode);
        },
        nodeClick(treeNode, Node, comp) { // 点击事件  treeNode:当前节点 Node: 节点对象Node  comp:组件本身
            this.currentNode = treeNode;
            this.$emit('node-click', treeNode, Node, comp);

            let path = this.$refs.tree.getNodePath(treeNode.id);
            this.$emit('updatePath', path);
        },
        deleteNode() { // 删除节点
            this.$confirm('删除后不能恢复，是否确认？', {title: '提示', type: 'warning'}).then(() => {
                let params = { ids: this.currentNode.id };
                delDeptTree(params).then(response => {
                    if (response.data.code == 1000) {
                        let node = this.$refs.tree.getNode(this.currentNode.id);
                        if(node) { // 从树中 删除节点
                            this.$refs.tree.remove(node);
                            if(this.treeData[0])  this.$emit('updateCurrentNode', this.treeData[0]);
                            this.$notify({
                                title: "提示",
                                message: "删除成功！",
                                type: "success"
                            });
                        }
                    }
                });
            }).catch(() => {})
        },
        updateNodeFun(data) { // 更新节点信息
            let Node = this.$refs.tree.getNode(data.id);
            if(Node) {
                let childNodes = Node.childNodes;
                let newdata = {
                    ...data,
                    children: childNodes.map(item => item.data)
                }
                Node.data = newdata;

                this.$emit('updateCurrentNode', data);

                // 更新面包屑
                let path = this.$refs.tree.getNodePath(data.id);
                this.$emit('updatePath', path);
            }
        },
        appendNodeFun(data) { // 当前节点追加新节点
            let parentNode = this.$refs.tree.getNode(this.currentNode.id);
            if(parentNode && data.parentId == this.currentNode.id) {
                this.$refs.tree.append(data, parentNode);
                parentNode.expanded = true;
            }else {
                this.deptTreeInit();
            }
        },
        upNode() { // 上移节点
            let parentNode = this.$refs.tree.getNode(this.currentNode.id).parent;
            let cNode = this.$refs.tree.getNode(this.currentNode.id);
            let childNodes = this.$refs.tree.getNode(this.currentNode.id).parent.childNodes;

            let index = childNodes.findIndex(item => item.data.id == this.currentNode.id);
            if(index <= 0) {
                return
            }

            let currentChild = childNodes.filter(v => v.id !== cNode.id);
            if(currentChild.length) {
                currentChild.splice(index - 1, 0, cNode);
                if(currentChild.length) {
                    let ids = currentChild.map(item => item.data.id).join();
                    let params = {
                        ids: ids
                    }
                    this.loading = true;
                    updateDeptOrder(params).then(res => {
                        if(res.data.code == 1000) {
                            this.$notify({
                                title: '提示',
                                type: 'success',
                                message: '操作成功'
                            })
                            parentNode.childNodes = currentChild;
                        }
                        this.loading = false;
                    }).catch(error => {
                        this.loading = false;
                    })
                }
            }
        },
        downNode() { // 下移节点
            let parentNode = this.$refs.tree.getNode(this.currentNode.id).parent;
            let cNode = this.$refs.tree.getNode(this.currentNode.id);
            let childNodes = this.$refs.tree.getNode(this.currentNode.id).parent.childNodes;

            let index = childNodes.findIndex(item => item.data.id == this.currentNode.id);
            if(index >= (childNodes.length - 1)) {
                return
            }

            let currentChild = childNodes.filter(v => v.id !== cNode.id);
            if(currentChild.length) {
                currentChild.splice(index + 1, 0, cNode);
                if(currentChild.length) {
                    let ids = currentChild.map(item => item.data.id).join();
                    let params = {
                        ids: ids
                    }
                    this.loading = true;
                    updateDeptOrder(params).then(res => {
                        if(res.data.code == 1000) {
                            this.$notify({
                                title: '提示',
                                type: 'success',
                                message: '操作成功'
                            })
                            parentNode.childNodes = currentChild;
                        }
                        this.loading = false;
                    }).catch(error => {
                        this.loading = false;
                    })
                }
            }
        },
        updateKeyChildren(key) { // 更新子级的数据  key: 节点key
            let node = this.$refs.tree.getNode(key);
            if(node) {
                this.$refs.tree.updateKeyChildren(key, data=[]);
            }
        },
        transNode() { // 转移
            let params = {
                id: this.currentNode.id
            }
            getDeptInfo(params).then(res => {
                if(res.data.code == 1000) {
                    let data = res.data.data;
                    if(data) {
                        this.ruleForm.parentId = data.parentId;
                        this.ruleForm.parentName = data.parentName;
                        this.ruleForm.orderNum = data.orderNum;
                    }
                }
            })
            this.show = true;
        },
        submitFun() { // 转移提交
            this.$refs.form.validate(valid => {
                if(valid) {
                    let params = {
                        id: this.currentNode.id,
                        parentId: this.ruleForm.parentId,
                        parentName: this.ruleForm.parentName,
                        orderNum: this.ruleForm.orderNum
                    }
                    this.loading2 = true;
                    updateDeptTree(params).then(res => {
                        if(res.data.code == 1000) {
                            this.$notify({
                                title: '提示',
                                type: 'success',
                                message: '转移成功！'
                            })
                            this.deptTreeInit();
                            this.closeDialog();
                        }
                        this.loading2 = false;
                    }).catch(error => {
                        this.loading2 = false;
                    })
                }
            })
        },
        resetForm() { // 转移重置
            this.$refs.form.resetFields();
        },
        closeDialog() { // 关闭转移
            this.show = false;
            this.resetForm();
        },
        closeDeptDlg() { // 关闭新增机构 弹窗
            this.show2 = false;
            this.$refs.form2.resetFields();
        },
        saveDeptFun() { // 新增机构 保存
            this.$refs.form2.validate(valid => {
                if(valid) {
                    let params = {
                        name: this.ruleForm.name, // 机构名称
                        parentId: this.currentNode.id,
                        parentName: this.currentNode.name,
                        chargUserIds: this.ruleForm.chargUserIds.join(), // 主管
                        chargUserNames: this.ruleForm.chargUserNames.join(),
                        descr: this.ruleForm.descr,
                        isGroup: this.ruleForm.isGroup, // 是否创建群组
                        statusId: 'ACTIVE',
                        statusName: '启用'
                    }
                    this.loading4 = true;
                    saveDeptTree(params).then(res => {
                        if(res.data.code == 1000) {
                            this.$notify({
                                title: '提示', 
                                type: 'success',
                                message: '新增成功！'
                            })
                            if(this.currentNode.id) {
                                this.appendNodeFun(res.data.data);
                            }else {
                                this.deptTreeInit();
                            }
                            this.closeDeptDlg();
                        }
                        this.loading4 = false;
                    }).catch(error => {
                        this.loading4 = false;
                    })
                }
            })
        },
    }
}
</script>

<style lang="scss" scoped>
.lazy-tree {
    height: 100%;
    .inner-wrap {
        height: 100%;
        display: flex;
        flex-direction: column;
        .btn-box {
            height: 36px;
            padding: 10px;
            text-align: right;
            margin: 6px 0 7px;
            /deep/ {
                .el-button--text {
                    padding: 0;
                    i {
                        font-size: 14px;
                    }
                }
            }
        }
        .search-bar {
            margin-bottom: 10px;
        }
        .tree-box {
            flex: 1;
            padding: 20px;
            overflow: auto;
            /deep/ {
                .el-tree {
                    display: inline-block !important;
                    min-width: 100%;
                }
            }
        }
    }
}
</style>